﻿Imports System
Imports System.CodeDom
Imports System.Globalization
Imports System.Text
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.Activities.Rules
    Friend Class ArrayIndexerExpression
        Inherits RuleExpressionInternal
        ' Methods
        Friend Overrides Sub AnalyzeUsage(ByVal expression As CodeExpression, ByVal analysis As RuleAnalysis, ByVal isRead As Boolean, ByVal isWritten As Boolean, ByVal qualifier As RulePathQualifier)
            Dim expression2 As CodeArrayIndexerExpression = DirectCast(expression, CodeArrayIndexerExpression)
            RuleExpressionWalker.AnalyzeUsage(analysis, expression2.TargetObject, isRead, isWritten, qualifier)
            Dim i As Integer
            For i = 0 To expression2.Indices.Count - 1
                RuleExpressionWalker.AnalyzeUsage(analysis, expression2.Indices.Item(i), True, False, Nothing)
            Next i
        End Sub

        Friend Overrides Function Clone(ByVal expression As CodeExpression) As CodeExpression
            Dim expression2 As CodeArrayIndexerExpression = DirectCast(expression, CodeArrayIndexerExpression)
            Dim targetObject As CodeExpression = RuleExpressionWalker.Clone(expression2.TargetObject)
            Dim indices As CodeExpression() = New CodeExpression(expression2.Indices.Count  - 1) {}
            Dim i As Integer
            For i = 0 To indices.Length - 1
                indices(i) = RuleExpressionWalker.Clone(expression2.Indices.Item(i))
            Next i
            Return New CodeArrayIndexerExpression(targetObject, indices)
        End Function

        Friend Overrides Sub Decompile(ByVal expression As CodeExpression, ByVal stringBuilder As StringBuilder, ByVal parentExpression As CodeExpression)
            Dim expression2 As CodeArrayIndexerExpression = DirectCast(expression, CodeArrayIndexerExpression)
            Dim targetObject As CodeExpression = expression2.TargetObject
            If (targetObject Is Nothing) Then
                Dim exception As New RuleEvaluationException(String.Format(CultureInfo.CurrentCulture, Messages.NullIndexerTarget, New Object(0  - 1) {}))
                exception.Data.Item("ErrorObject") = expression2
                Throw exception
            End If
            If ((expression2.Indices Is Nothing) OrElse (expression2.Indices.Count = 0)) Then
                Dim exception2 As New RuleEvaluationException(String.Format(CultureInfo.CurrentCulture, Messages.MissingIndexExpressions, New Object(0  - 1) {}))
                exception2.Data.Item("ErrorObject") = expression2
                Throw exception2
            End If
            RuleExpressionWalker.Decompile(stringBuilder, targetObject, expression2)
            stringBuilder.Append("["c)
            RuleExpressionWalker.Decompile(stringBuilder, expression2.Indices.Item(0), Nothing)
            Dim i As Integer
            For i = 1 To expression2.Indices.Count - 1
                stringBuilder.Append(", ")
                RuleExpressionWalker.Decompile(stringBuilder, expression2.Indices.Item(i), Nothing)
            Next i
            stringBuilder.Append("]"c)
        End Sub

        Friend Overrides Function Evaluate(ByVal expression As CodeExpression, ByVal execution As RuleExecution) As RuleExpressionResult
            Dim expression2 As CodeArrayIndexerExpression = DirectCast(expression, CodeArrayIndexerExpression)
            Dim obj2 As Object = RuleExpressionWalker.Evaluate(execution, expression2.TargetObject).Value
            If (obj2 Is Nothing) Then
                Dim exception As New RuleEvaluationException(String.Format(CultureInfo.CurrentCulture, Messages.TargetEvaluatedNullIndexer, New Object(0  - 1) {}))
                exception.Data.Item("ErrorObject") = expression2
                Throw exception
            End If
            Dim count As Integer = expression2.Indices.Count
            Dim indexerArguments As Long() = New Long(count  - 1) {}
            Dim i As Integer
            For i = 0 To count - 1
                Dim expressionType As Type = execution.Validation.ExpressionInfo(expression2.Indices.Item(i)).ExpressionType
                Dim operandValue As Object = RuleExpressionWalker.Evaluate(execution, expression2.Indices.Item(i)).Value
                indexerArguments(i) = CLng(Executor.AdjustType(expressionType, operandValue, GetType(Long)))
            Next i
            Return New RuleArrayElementResult(DirectCast(obj2, Array), indexerArguments)
        End Function

        Friend Overrides Function Match(ByVal expression As CodeExpression, ByVal comperand As CodeExpression) As Boolean
            Dim expression2 As CodeArrayIndexerExpression = DirectCast(expression, CodeArrayIndexerExpression)
            Dim expression3 As CodeArrayIndexerExpression = DirectCast(comperand, CodeArrayIndexerExpression)
            If Not RuleExpressionWalker.Match(expression2.TargetObject, expression3.TargetObject) Then
                Return False
            End If
            If (expression2.Indices.Count <> expression3.Indices.Count) Then
                Return False
            End If
            Dim i As Integer
            For i = 0 To expression2.Indices.Count - 1
                If Not RuleExpressionWalker.Match(expression2.Indices.Item(i), expression3.Indices.Item(i)) Then
                    Return False
                End If
            Next i
            Return True
        End Function

        Friend Overrides Function Validate(ByVal expression As CodeExpression, ByVal validation As RuleValidation, ByVal isWritten As Boolean) As RuleExpressionInfo
            Dim item As ValidationError = Nothing
            Dim expressionType As Type = Nothing
            Dim newParent As CodeArrayIndexerExpression = DirectCast(expression, CodeArrayIndexerExpression)
            Dim targetObject As CodeExpression = newParent.TargetObject
            If (targetObject Is Nothing) Then
                item = New ValidationError(Messages.NullIndexerTarget, &H53D)
                item.UserData.Item("ErrorObject") = newParent
                validation.Errors.Add(item)
                Return Nothing
            End If
            If TypeOf targetObject Is CodeTypeReferenceExpression Then
                item = New ValidationError(Messages.IndexersCannotBeStatic, &H53D)
                item.UserData.Item("ErrorObject") = newParent
                validation.Errors.Add(item)
                Return Nothing
            End If
            If ((newParent.Indices Is Nothing) OrElse (newParent.Indices.Count = 0)) Then
                item = New ValidationError(Messages.MissingIndexExpressions, &H53D)
                item.UserData.Item("ErrorObject") = newParent
                validation.Errors.Add(item)
                Return Nothing
            End If
            Try 
                If Not validation.PushParentExpression(newParent) Then
                    Return Nothing
                End If
                Dim info As RuleExpressionInfo = RuleExpressionWalker.Validate(validation, newParent.TargetObject, False)
                If (info Is Nothing) Then
                    Return Nothing
                End If
                expressionType = info.ExpressionType
                If (expressionType Is Nothing) Then
                    Return Nothing
                End If
                If (expressionType Is GetType(NullLiteral)) Then
                    item = New ValidationError(Messages.NullIndexerTarget, &H53D)
                    item.UserData.Item("ErrorObject") = newParent
                    validation.Errors.Add(item)
                    Return Nothing
                End If
                If Not expressionType.IsArray Then
                    item = New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.CannotIndexType, New Object() { RuleDecompiler.DecompileType(expressionType) }), &H19B)
                    item.UserData.Item("ErrorObject") = newParent
                    validation.Errors.Add(item)
                    Return Nothing
                End If
                Dim arrayRank As Integer = expressionType.GetArrayRank
                If (newParent.Indices.Count <> arrayRank) Then
                    item = New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.ArrayIndexBadRank, New Object() { arrayRank }), &H19C)
                    item.UserData.Item("ErrorObject") = newParent
                    validation.Errors.Add(item)
                    Return Nothing
                End If
                Dim flag As Boolean = False
                Dim i As Integer
                For i = 0 To newParent.Indices.Count - 1
                    Dim expression4 As CodeExpression = newParent.Indices.Item(i)
                    If (expression4 Is Nothing) Then
                        item = New ValidationError(Messages.NullIndexExpression, &H53D)
                        item.UserData.Item("ErrorObject") = newParent
                        validation.Errors.Add(item)
                        flag = True
                        [Continue] For
                    End If
                    If TypeOf expression4 Is CodeDirectionExpression Then
                        item = New ValidationError(Messages.IndexerArgCannotBeRefOrOut, &H19D)
                        item.UserData.Item("ErrorObject") = expression4
                        validation.Errors.Add(item)
                        flag = True
                    End If
                    If TypeOf expression4 Is CodeTypeReferenceExpression Then
                        item = New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, New Object() { expression4.GetType.FullName }), &H548)
                        item.UserData.Item("ErrorObject") = expression4
                        validation.AddError(item)
                        flag = True
                    End If
                    Dim info2 As RuleExpressionInfo = RuleExpressionWalker.Validate(validation, expression4, False)
                    If (Not info2 Is Nothing) Then
                        Dim type As Type = info2.ExpressionType
                        Select Case Type.GetTypeCode(type)
                            Case TypeCode.Char, TypeCode.[SByte], TypeCode.Byte, TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.Int64
                                [Continue]
                        End Select
                        item = New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.ArrayIndexBadType, New Object() { RuleDecompiler.DecompileType(type) }), &H19E)
                        item.UserData.Item("ErrorObject") = expression4
                        validation.Errors.Add(item)
                        flag = True
                        [Continue] For
                    End If
                    flag = True
                Next i
                If flag Then
                    Return Nothing
                End If
            Finally
                validation.PopParentExpression
            End Try
            Return New RuleExpressionInfo(expressionType.GetElementType)
        End Function

    End Class
End Namespace

